using Voodoo.Sauce.Internal.Analytics;

namespace Voodoo.Sauce.Core
{
	public static class IAPAnalytics
	{
		private static EnvironmentSettings.Server? _server;

		private static EnvironmentSettings.Server Server
		{
			get
			{
				if (!_server.HasValue)
				{
					_server = EnvironmentSettings.GetAnalyticsServer();
				}
				return _server.Value;
			}
		}

		internal static void Start(ProductReceivedInfo product)
		{
			FormatPurchaseEvent(product, null, generatePurchaseId: true).purchaseTransactionId = "";
		}

		internal static void Start(string productId)
		{
			string purchaseUniqueId = TransactionUtility.GetPurchaseUniqueId(productId, generate: true);
			string lowerCaseEnvironmentFromServer = EnvironmentSettings.GetLowerCaseEnvironmentFromServer(Server);
			new VoodooIAPAnalyticsInfo(purchaseUniqueId)
			{
				productId = productId,
				environment = lowerCaseEnvironmentFromServer
			};
		}

		internal static void Process(ProductReceivedInfo product)
		{
			FormatPurchaseEvent(product, null);
		}

		internal static void Failure(ProductReceivedInfo product, PurchaseValidation purchaseValidation, VoodooPurchaseFailureReason reason, string description)
		{
			VoodooIAPAnalyticsInfo voodooIAPAnalyticsInfo = FormatPurchaseEvent(product, purchaseValidation?.isRestorationPurchase);
			voodooIAPAnalyticsInfo.failureReason = reason.ToString();
			voodooIAPAnalyticsInfo.failureDescription = description;
		}

		internal static void Failure(string productId, VoodooPurchaseFailureReason reason, string description)
		{
			string purchaseUniqueId = TransactionUtility.GetPurchaseUniqueId(productId, generate: false);
			string lowerCaseEnvironmentFromServer = EnvironmentSettings.GetLowerCaseEnvironmentFromServer(Server);
			new VoodooIAPAnalyticsInfo(purchaseUniqueId)
			{
				productId = productId,
				environment = lowerCaseEnvironmentFromServer,
				failureReason = reason.ToString(),
				failureDescription = description
			};
		}

		internal static void Validate(ProductReceivedInfo product, PurchaseValidation purchaseValidation)
		{
			FormatPurchaseEvent(product, purchaseValidation?.isRestorationPurchase);
		}

		internal static void Reward(ProductReceivedInfo product, PurchaseValidation purchaseValidation)
		{
			FormatPurchaseEvent(product, purchaseValidation?.isRestorationPurchase);
		}

		internal static void ServerError(ProductReceivedInfo product, PurchaseValidation purchaseValidation, IAPServerError serverError)
		{
			FormatPurchaseEvent(product, purchaseValidation?.isRestorationPurchase);
		}

		internal static void TrackIAPRevenues(ProductReceivedInfo product, bool isPurchaseRestored, bool isPurchaseValidated)
		{
			VoodooIAPAnalyticsInfo voodooIAPAnalyticsInfo = FormatPurchaseEvent(product, isPurchaseRestored, generatePurchaseId: true);
			voodooIAPAnalyticsInfo.isPurchaseValidated = isPurchaseValidated;
			voodooIAPAnalyticsInfo.environment = voodooIAPAnalyticsInfo.environment.ToLower();
			TransactionUtility.DeletePurchaseId(product.ProductId);
		}

		private static VoodooIAPAnalyticsInfo FormatPurchaseEvent(ProductReceivedInfo product, bool? purchaseRestored, bool generatePurchaseId = false)
		{
			string purchaseUniqueId = TransactionUtility.GetPurchaseUniqueId(product.ProductId, generatePurchaseId);
			double price = product.LocalizedPriceInfo.price;
			string isoCurrencyCode = product.LocalizedPriceInfo.isoCurrencyCode;
			string productId = product.ProductId;
			string productName = product.ProductName;
			PurchaseProductType productType = product.ProductType;
			string transactionID = product.TransactionID;
			string lowerCaseEnvironmentFromServer = EnvironmentSettings.GetLowerCaseEnvironmentFromServer(Server);
			return new VoodooIAPAnalyticsInfo(purchaseUniqueId, price, isoCurrencyCode, productId, productName, productType, transactionID, purchaseRestored, lowerCaseEnvironmentFromServer);
		}
	}
}
